
data Action = N | S | E | W | L | R | F deriving (Show, Eq)
data Instruction = Instruction Action Double deriving (Show)

type Position = (Double, Double)
type Angle = Double 
data Ship = Ship Angle Position deriving (Show)

parseAction :: Char -> Action
parseAction c = case c of 
    'N' -> N
    'S' -> S
    'E' -> E
    'W' -> W
    'L' -> L
    'R' -> R
    'F' -> F
 
parseInstruction :: String -> Instruction
parseInstruction string = 
    Instruction (parseAction action) (read value)
    where
        action = head string
        value = tail string 

parseInput :: String -> [Instruction]
parseInput = map parseInstruction . lines

angleToRadian :: Double -> Double
angleToRadian angle = (pi / 180) * angle

move :: Ship -> Instruction -> Ship
move (Ship angle (x,y)) (Instruction action value) = 
    case action of
        N -> Ship angle (x,y+value)
        S -> Ship angle (x,y-value)
        E -> Ship angle (x+value,y) 
        W -> Ship angle (x-value,y) 
        L -> Ship (angle+value) (x,y)
        R -> Ship (angle-value) (x,y)
        F -> Ship (angle) (x+dx,y+dy)
            where
                radian = angleToRadian angle
                dx = cos radian * value
                dy = sin radian * value
                
manhattanDistance :: Ship -> Double
manhattanDistance (Ship _ (x,y)) = abs x + abs y

main :: IO ()
main = do
    input <- readFile "input.txt"
    print . manhattanDistance 
          . foldl move (Ship 0 (0,0)) 
          . parseInput $ input
            